use crate::prelude::*;

#[system]
#[read_component(Point)]
#[read_component(ChasingPlayer)]
#[read_component(FieldOfView)]
#[read_component(Health)]
#[read_component(Player)]
pub fn chasing(
    #[resource] map: &Map,
    ecs: &SubWorld,
    commands: &mut CommandBuffer,
) {
    // 仅查找带有Point位置属性和ChasingPlayer标签的实体
    let mut movers = <(Entity, &Point, &ChasingPlayer, &FieldOfView)>::query();

    // 所有包含Point和Health这两个组件的实体
    let mut positions = <(Entity, &Point, &Health)>::query();

    // 只包含Point位置属性和Player标签的实体，并返回玩家角色的位置
    let mut player = <(&Point, &Player)>::query();

    // 将玩家角色的位置以及该位置对应图块的索引编号暂存起来
    let player_pos = player
        .iter(ecs)
        .nth(0)
        .unwrap()
        .0;
    let player_idx = map_idx(player_pos.x, player_pos.y);

    let search_targets = vec![player_idx];
    let dijkstra_map = DijkstraMap::new(
        SCREEN_WIDTH,
        SCREEN_HEIGHT,
        &search_targets,
        map, 
        1024.0,
    );

    movers.iter(ecs).for_each(|(entity, pos, _, fov,)| {

        if !fov.visible_tiles.contains(&player_pos) {
            return;
        }

        let idx = map_idx(pos.x, pos.y);
        if let Some(destination) = DijkstraMap::find_lowest_exit(&dijkstra_map, idx, map){
            let distance = DistanceAlg::Pythagoras.distance2d(*pos, *player_pos);
            let destination = if distance > 1.2 {
                map.index_to_point2d(destination)
            }else{
                *player_pos
            };

            let mut attacked = false;
            positions
                .iter(ecs)
                .filter(|(_, target_pos, _)| **target_pos == destination)
                .for_each(|(victim, _, _)| {
                    if ecs.entry_ref(*victim).unwrap().get_component::<Player>().is_ok() {
                        commands.push(((), WantsToAttack{attacker: *entity, victim: *victim}));
                    }

                    attacked = true;
                });
            
            if !attacked {
                commands.push(((), WantsToMove{entity: *entity, destination}));
            }
        }

    });
}